# !usr/bin/python
# -*-coding: utf-8-*-
# Filename: HttpHead.py

class HttpHead():
	'''http head info
	头名称全部转为小写

	getTags()
	getHeadStr()
	addHeadKey()
	delHeadKey()
	updateKey()
	updateKey2()'''

	# complete
	_Headcomplete = {}
	# headstring
	_HeadStr = None
	# headstr修改flag
	_HeadModify = False
	# Request?Response
	# True: Request ; Flase: Response
	_IsRequest = None

	def __init__( self, headstr = None ):
		if headstr == None:
			return

		self._Headcomplete = {}

		count = headstr.find( '\r\n\r\n' )
		if(  count == -1 ):
			return

		self._HeadStr = headstr[0:count+4]

		Value1 = self._HeadStr[0:count].split( '\r\n' )

		# Head头信息提取 Request?Response
		count = Value1[0].find( 'HTTP/' )
		if( count == -1 ):
			return
		elif( count == 0 ):
			# Response
			self._IsRequest = False
			# Response 状态
			self._Headcomplete['Status'] = Value1[0][9:]
		else :
			# Request
			self._IsRequest = True
			# 分析
			Value11 = Value1[0].split( ' ' )

			# Request 方法
			self._Headcomplete['Method'] = Value11[0]
			
			# URL
			if( 3 > len( Value11 ) ):
				self._Headcomplete['Url'] = None
			else:
				self._Headcomplete['Url'] = Value11[1]

		# HTTP协议版本
		if( -1 != Value1[0].find( 'HTTP/1.0' ) ):
			self._Headcomplete['HttpVersion'] = 'HTTP/1.0'
		elif( -1 != Value1[0].find( 'HTTP/1.1' ) ):
			self._Headcomplete['HttpVersion'] = 'HTTP/1.1'

		# 其他头信息获取
		for i in range( 1, len(Value1) ):
			Value2 = Value1[i].split( ': ' )
			if( len(Value2) == 2 ):
				self._Headcomplete[Value2[0].lower()] = Value2[1]

	def getTags( self, tagname = None ):
		'''return Tag info 
		tagname为None时，以字典形式返回所有头信息'''

		try:
			if( tagname == None ):
				return( self._Headcomplete )
			else:
				# return( self._Headcomplete[ tagname ] )
				return (self._Headcomplete.get(tagname.lower(), None))
		except:
			return( None )

	def getHeadStr( self ):
		'''return head string
		返回处理后的头信息，包含结尾的\r\n\r\n.'''

		# Request Head String
		if self._HeadModify == True:
			self._HeadStr = self.headComposing( self._Headcomplete )
			self._HeadModify = False

		return( self._HeadStr )

	def addHeadKey( self, keypair = None ):
		'''在头信息末尾插入新条目'''

		if( keypair == None ):
			return

		count = keypair.find(': ')
		if( count == -1 ):
			return

		try:
			# 头字典追加
			self._Headcomplete[keypair[0:count].lower()] = keypair[count+2:]
			self._HeadModify = True
		except:
			pass

	def delHeadKey( self, key ):
		'''从头信息中删除条目'''

		if( key == None ):
			return

		# 统一大小写
		key = key.lower()

		# 从头信息词典中删除
		try:
			if key in self._Headcomplete:
				del self._Headcomplete[key]
				self._HeadModify = True
			else:
				return
		except:
			pass

	def updateKey( self, key, value):
		'''头信息变更,不存在则返回'''

		if (value == None):
			return

		# 统一大小写
		key = key.lower()

		# 头信息词典替换
		try:
			if key in self._Headcomplete:
				self._Headcomplete[key] = value
				self._HeadModify = True
		except:
			pass

	def updateKey2( self, key, value):
		'''头信息变更,不存在则追加'''

		if (value == None):
			return

		# 统一大小写
		key = key.lower()

		# 头信息词典替换
		try:
			if key in self._Headcomplete:
				self._Headcomplete[key] = value
			else:
				self.addHeadKey(key + ': ' + value)
		except:
			pass


	def headComposing( self, headdic ):
		headstr = ''

		if (self._IsRequest == True):
			# Method
			headstr = headdic['Method']
			# Url
			headstr += ' ' + headdic['Url']
			# Http Version
			headstr += ' ' + headdic['HttpVersion']
		else:
			# Http Version
			headstr += headdic['HttpVersion']
			# Status
			headstr += ' ' + headdic['Status']
		# other
		headstr += '\r\n'
		for key in self._Headcomplete:
			if key == 'Method' or key == 'Url' or key == 'HttpVersion' or key == 'Status':
				continue
			headstr += key + ': ' + headdic[key] + '\r\n'
		# end
		headstr += '\r\n'

		return headstr

class HttpHead2():
	'''http head info
	保持原有头名称的大小写

	getTags()
	getHeadStr()
	addHeadKey()
	delHeadKey()
	updateKey()
	updateKey2()'''

	# complete
	_Headcomplete = {}
	# headstart
	_HeadStr = None
	# Request?Response
	# True: Request ; Flase: Response
	_IsRequest = None

	def __init__( self, headstr = None ):
		if headstr == None:
			return

		self._Headcomplete = {}

		count = headstr.find( '\r\n\r\n' )
		if(  count == -1 ):
			return

		self._HeadStr = headstr[0:count+4]

		Value1 = self._HeadStr[0:count].split( '\r\n' )

		# Head头信息提取 Request?Response
		count = Value1[0].find( 'HTTP/' )
		if( count == -1 ):
			return
		elif( count == 0 ):
			# Response
			self._IsRequest = False
			# Response 状态
			self._Headcomplete['Status'] = Value1[0][9:]
		else :
			# Request
			self._IsRequest = True
			# 分析
			Value11 = Value1[0].split( ' ' )

			# Request 方法
			self._Headcomplete['Method'] = Value11[0]
			
			# URL
			if( 3 > len( Value11 ) ):
				self._Headcomplete['Url'] = None
			else:
				self._Headcomplete['Url'] = Value11[1]

		# HTTP协议版本
		if( -1 != Value1[0].find( 'HTTP/1.0' ) ):
			self._Headcomplete['HttpVersion'] = 'HTTP/1.0'
		elif( -1 != Value1[0].find( 'HTTP/1.1' ) ):
			self._Headcomplete['HttpVersion'] = 'HTTP/1.1'

		# 其他头信息获取
		for i in range( 1, len(Value1) ):
			Value2 = Value1[i].split( ': ' )
			if( len(Value2) == 2 ):
				self._Headcomplete[Value2[0]] = Value2[1]

	def getTags( self, tagname = None ):
		'''return Tag info 
		tagname为None时，以字典形式返回所有头信息'''

		try:
			if( tagname == None ):
				return( self._Headcomplete )
			else:
				# return( self._Headcomplete[ tagname ] )
				return (self._Headcomplete.get(tagname, None))
		except:
			return( None )

	def getHeadStr( self ):
		'''return head string
		返回处理后的头信息，包含结尾的\r\n\r\n.'''

		if( self._IsRequest == False ):
			# Response 情况暂不处理
			# return( None )
			return( self._HeadStr )
		else:
			# Request Head String
			return( self._HeadStr )

	def addHeadKey( self, keypair = None ):
		'''在头信息末尾插入新条目'''

		if( keypair == None ):
			return

		count = keypair.find(': ')
		if( count == -1 ):
			return

		# 头信息追加
		self._HeadStr = self._HeadStr[0:-2] + keypair + '\r\n\r\n'
		# 头字典追加
		self._Headcomplete[keypair[0:count]] = keypair[count+2:]

	def delHeadKey( self, key ):
		'''从头信息中删除条目'''

		if( key == None ):
			return

		# 不含有该条目则返回
		count = self._HeadStr.find( key )
		if( count == -1 ):
			return
		count1 = self._HeadStr[count:].find( '\r\n' )
		if( count1 == -1 ):
			return

		count1 = count + count1
		# 该条目位于最后
		if( len(self._HeadStr) - count1 < len('\r\n\r\n') + 1 ): 
			self._HeadStr = self._HeadStr[0:count] + '\r\n\r\n'
		# 该条目位于中间
		else:
			self._HeadStr = self._HeadStr[0:count] + self._HeadStr[count1+2:]

		# 从头信息词典中删除
		try:
			del self._Headcomplete[key]
		except:
			pass

	def updateKey( self, key, value):
		'''头信息变更,不存在则返回'''

		if (value == None):
			return

		# 不含有该条目则返回
		count = self._HeadStr.find( key )
		if( count == -1 ):
			return
		count1 = self._HeadStr[count:].find( '\r\n' )
		if( count1 == -1 ):
			return
		count1 = count + count1
		count2 = self._HeadStr[count:count1].find( ': ' )
		self._HeadStr = self._HeadStr[0:count+count2+2] + value + self._HeadStr[count1:]

		# 头信息词典替换
		try:
			self._Headcomplete[key] = value
		except:
			pass

	def updateKey2( self, key, value):
		'''头信息变更,不存在则追加'''

		if (value == None):
			return

		flg = True
		# 不含有该条目则增加
		count = self._HeadStr.find( key )
		if( count == -1 ):
			flg = False
		count1 = self._HeadStr[count:].find( '\r\n' )
		if( count1 == -1 ):
			flg = False

		if (flg == True):
			count1 = count + count1
			count2 = self._HeadStr[count:count1].find( ': ' )
			self._HeadStr = self._HeadStr[0:count+count2+2] + value + self._HeadStr[count1:]

			# 头信息词典替换
			try:
				self._Headcomplete[key] = value
			except:
				pass
		else:
			self.addHeadKey(key + ': ' + value)

# myhead = HttpHead( 'GET http://start.firefoxchina.cn/ HTTP/1.1\r\nHost: www.lixingke.com\r\n\r\nqwe: qweqwe' )
myhead = HttpHead( 'HTTP/1.1 304 Not Modified\r\nServer: nginx/1.4.7\r\nDate: Sat, 29 Mar 2014 00:49:29 GMT\r\nIf-Modified-Since: Tue, 03 Jun 2014 03:52:05 GMT\r\nIf-None-Match: "538d4665-264"\r\nCache-Control: max-age=0\r\nLast-Modified: Sun, 23 Mar 2014 06:53:21 GMT\r\nConnection: keep-alive\r\nETag: "532e84e1-264"\r\n\r\n' )
# myhead = HttpHead( 'GET http://www.cnblogs.com/mvc/blog/signature.aspx?blogId=141995&blogApp=xfuture HTTP/1.1\r\nHost: www.cnblogs.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:34.0) Gecko/20100101 Firefox/34.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: ja,en-us;q=0.7,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nCookie: __utma=226521935.670419876.1403829288.1416359118.1416900625.11; __utmz=226521935.1413510235.7.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); _ga=GA1.2.670419876.1403829288; lzstat_uv=28970252911756942451|2582060@2817822; CNZZDATA5219645=cnzz_eid%3D328059846-1417399388-%26ntime%3D1417399388; CNZZDATA2909622=cnzz_eid%3D838768860-1417579826-http%253A%252F%252Fwww.google.co.jp%252F%26ntime%3D1417579826; AJSTAT_ok_times=2\r\nCache-Control: max-age=0\r\nProxy-Connection: close\r\n\r\n' )
# myhead.updateKey2('If-None-Match','abcd1234')
# myhead.addHeadKey('hello1: aabb1')
# myhead.addHeadKey('hello2: aabb2')
# myhead.addHeadKey('hello3: aabb3')
print( myhead.getHeadStr() )
# fp = open ('t01.txt', 'wb')
# fp.write(myhead.getHeadStr())
# fp.close()